home *** CD-ROM | disk | FTP | other *** search
/ Aminet 44 / Aminet 44 (2001)(GTI - Schatztruhe)[!][Aug 2001].iso / Aminet / dev / moni / systemviewer.lha / SysSemaphore.c < prev    next >
C/C++ Source or Header  |  2001-04-25  |  16KB  |  652 lines

  1. /****h* SysSemaphore.c [1.1] ******************************************
  2. *
  3. * NAME
  4. *    SysSemaphore.c
  5. *
  6. * DESCRIPTION
  7. *    Display a list of all Semaphores currently known to the OS.
  8. *
  9. * FUNCTIONAL INTERFACE:
  10. *
  11. *
  12. *
  13. * FUNCTIONS FROM SysCommon.c:
  14. *
  15. *   PUBLIC BOOL SanityCheck( char *msg, ULONG addr );
  16. *
  17. *   PUBLIC int  SetupSystemList( (*OpenWindowFunc)( void ) );
  18. *
  19. *   PUBLIC void ShutdownSystemList( void );
  20. *
  21. *   PUBLIC void ModifyListView( struct Gadget *lv, 
  22. *                               struct Window *w,
  23. *                               struct List   *list,
  24. *                               struct Gadget *strgadget
  25. *                             );
  26. *
  27. *  GUI Designed by : Jim Steichen
  28. *
  29. ***********************************************************************
  30. *
  31. */
  32.  
  33. #include <string.h>
  34.  
  35. #include <exec/types.h>
  36. #include <exec/execbase.h>
  37.  
  38. #include <AmigaDOSErrs.h>
  39.  
  40. #include <intuition/intuition.h>
  41. #include <intuition/classes.h>
  42. #include <intuition/classusr.h>
  43. #include <intuition/imageclass.h>
  44. #include <intuition/gadgetclass.h>
  45.  
  46. #include <libraries/gadtools.h>
  47.  
  48. #include <graphics/displayinfo.h>
  49. #include <graphics/gfxbase.h>
  50.  
  51. #include <clib/exec_protos.h>
  52. #include <clib/intuition_protos.h>
  53. #include <clib/gadtools_protos.h>
  54. #include <clib/graphics_protos.h>
  55. #include <clib/utility_protos.h>
  56. #include <clib/diskfont_protos.h>
  57.  
  58. #include "CPGM:GlobalObjects/CommonFuncs.h"
  59.  
  60. #include "SysLists.h"
  61.  
  62. #define SemLV      0
  63. #define Update     1
  64. #define Remove     2
  65. #define Cancel     3
  66. #define Release    4
  67. #define SemDisplay 5
  68.  
  69. #define SEM_CNT 6
  70.  
  71. #define LISTVIEWGADGET SemGadgets[ SemLV ]
  72. #define SEM_DISPLAY    SemGadgets[ SemDisplay ]
  73.  
  74. PUBLIC struct List *SListPtr = NULL;
  75.  
  76. PRIVATE char ver[] = "\0$VER: SysSemaphore 1.1 (25-Apr-2001) by J.T. Steichen\0";
  77.  
  78. PRIVATE struct Window       *SemWnd   = NULL;
  79. PRIVATE struct Gadget       *SemGList = NULL;
  80. PRIVATE struct IntuiMessage  SemMsg;
  81. PRIVATE struct Gadget       *SemGadgets[ SEM_CNT ];
  82.  
  83. PRIVATE UWORD  SemLeft   = 0;
  84. PRIVATE UWORD  SemTop    = 16;
  85. PRIVATE UWORD  SemWidth  = 632;
  86. PRIVATE UWORD  SemHeight = 250;
  87. PRIVATE UBYTE *SemWdt    = (UBYTE *) "System Semaphores Info:";
  88.  
  89. PUBLIC struct TextFont *SemFont    = NULL;
  90.  
  91. // -------------------------------------------------------------------
  92.  
  93. PRIVATE struct IntuiText SemIText[] = {
  94.  
  95.    2, 0, JAM1, 0, 7, NULL, 
  96.    "Address: Pri: Nest Queue    Count    Name                 Owner Task", 
  97.    NULL 
  98. };
  99.  
  100. #define MAXSEMS    30
  101. #define NODELENGTH 80
  102.  
  103. PRIVATE struct List SempList;
  104. PRIVATE struct Node SempNodes[ MAXSEMS      ] = { NULL, };
  105. PRIVATE UBYTE       NodeStrs[  MAXSEMS * NODELENGTH ] = "";
  106.  
  107. PRIVATE struct ListViewMem lvm = { 0, };
  108.     
  109. // -------------------------------------------------------------------
  110.  
  111. PRIVATE UWORD SemGTypes[] = {
  112.  
  113.    LISTVIEW_KIND, BUTTON_KIND, BUTTON_KIND,
  114.    BUTTON_KIND,   BUTTON_KIND, TEXT_KIND
  115. };
  116.  
  117. PRIVATE int SemLVClicked(   int whichitem );
  118. PRIVATE int UpdateClicked(  int dummy     );
  119. PRIVATE int RemoveClicked(  int dummy     );
  120. PRIVATE int CancelClicked(  int dummy     );
  121. PRIVATE int ReleaseClicked( int dummy     );
  122.  
  123. PRIVATE struct NewGadget SemNGad[] = {
  124.  
  125.      2,  14, 627, 184,                NULL, NULL, SemLV, 
  126.    0, NULL, (APTR) SemLVClicked,
  127.    
  128.      2, 226,  71,  17, (UBYTE *) "_Update", NULL, Update, 
  129.    PLACETEXT_IN, NULL, (APTR) UpdateClicked,
  130.  
  131.    396, 226,  71,  17, (UBYTE *) "Remove",  NULL, Remove, 
  132.    PLACETEXT_IN, NULL, (APTR) RemoveClicked,
  133.  
  134.    554, 226,  71,  17, (UBYTE *) "_Cancel", NULL, Cancel, 
  135.    PLACETEXT_IN, NULL, (APTR) CancelClicked,
  136.  
  137.     82, 226,  71,  17, (UBYTE *) "Release", NULL, Release, 
  138.    PLACETEXT_IN, NULL, (APTR) ReleaseClicked,
  139.  
  140.      2, 202, 611, 16,                 NULL, NULL, SemDisplay, 
  141.    0, NULL, NULL
  142. };
  143.  
  144. PRIVATE ULONG SemGTags[] = {
  145.  
  146.    GTLV_ShowSelected, NULL, 
  147.    LAYOUTA_Spacing,      2, TAG_DONE,
  148.  
  149.    GT_Underscore,      '_', TAG_DONE,
  150.    GA_Disabled,       TRUE, TAG_DONE,
  151.    GT_Underscore,      '_', TAG_DONE,
  152.    GA_Disabled,       TRUE, TAG_DONE,
  153.    GTTX_Border,       TRUE, TAG_DONE
  154. };
  155.  
  156. // -------------------------------------------------------------------
  157.  
  158. PRIVATE struct SignalSemaphore *CurrentSem = NULL;
  159.  
  160. PRIVATE int InitializeSemaphoreList( void )
  161. {
  162.    IMPORT struct ExecBase *SysBase;
  163.  
  164.    struct Task *tc = NULL;
  165.    char        *nm = NULL;
  166.    int          i  = 0;
  167.  
  168.    HideListFromView( LISTVIEWGADGET, SemWnd );
  169.  
  170.    Forbid();
  171.  
  172.      SListPtr   = &SysBase->SemaphoreList;
  173.      CurrentSem = (struct SignalSemaphore *) SListPtr->lh_Head;
  174.  
  175.      while (i < MAXSEMS && CurrentSem != NULL)
  176.         {       
  177.         tc = CurrentSem->ss_Owner;
  178.         nm = CurrentSem->ss_Link.ln_Name;
  179.         
  180.         sprintf( &NodeStrs[ i++ * NODELENGTH ], 
  181.                  "%08LX %4d %4u %08LX %08LX %-20.20s %-30.30s",
  182.                  CurrentSem, 
  183.                  CurrentSem->ss_Link.ln_Pri,
  184.                  CurrentSem->ss_NestCount,
  185.                  &CurrentSem->ss_WaitQueue,
  186.                  CurrentSem->ss_QueueCount,
  187.                  nm == NULL ? "** NO NAME **" : nm,      
  188.                  tc == NULL ? "** UNKNOWN **" : tc->tc_Node.ln_Name
  189.                );
  190.         
  191.         CurrentSem = (struct SignalSemaphore *) 
  192.                       CurrentSem->ss_Link.ln_Succ;
  193.         }
  194.  
  195.      // Reset CurrentSem to the Head of the list.
  196.      CurrentSem = (struct SignalSemaphore *) SListPtr->lh_Head;
  197.  
  198.    Permit();
  199.  
  200.    GT_SetGadgetAttrs( LISTVIEWGADGET, SemWnd, NULL,
  201.                       GTLV_Labels,       &SempList,
  202.                       GTLV_ShowSelected, SEM_DISPLAY,
  203.                       GTLV_Selected,     0, 
  204.                       GTLV_ItemHeight,   12,
  205.                       TAG_END
  206.                     );
  207.  
  208.    DisplayTitle( SemWnd, SemWdt );
  209.  
  210.    return( i );
  211. }
  212.  
  213. PRIVATE char wt[80] = { 0, }, *modtitle = &wt[0];
  214.  
  215. PRIVATE int SemLVClicked( int whichitem )
  216. {
  217.    ULONG addr = 0L;
  218.  
  219.    // Get address from the item:
  220.    
  221.    (void) stch_l( SempNodes[ whichitem ].ln_Name, (long *) &addr );
  222.    CurrentSem = addr;
  223.     
  224.    if (addr != NULL)
  225.       {
  226.       sprintf( modtitle, "%-45.45s  You Selected:  %08LX", SemWdt, addr );
  227.       DisplayTitle( SemWnd, modtitle );
  228.       
  229.       GT_SetGadgetAttrs( SEM_DISPLAY, SemWnd, NULL,
  230.                          GTTX_Text, 
  231.                          (STRPTR) &NodeStrs[ NODELENGTH * whichitem ],
  232.                          TAG_DONE
  233.                        );
  234.       }
  235.  
  236.    // Enable buttons because user selected a Semaphore from the ListView:
  237.  
  238.    GT_SetGadgetAttrs( SemGadgets[ Remove ], SemWnd, NULL,
  239.                       GA_Disabled, FALSE, TAG_DONE 
  240.                     );
  241.  
  242.    GT_SetGadgetAttrs( SemGadgets[ Release ], SemWnd, NULL,
  243.                       GA_Disabled, FALSE, TAG_DONE 
  244.                     );
  245.    
  246.    return( (int) TRUE );
  247. }
  248.  
  249. PRIVATE int UpdateClicked( int dummy )
  250. {
  251.    int i;
  252.    
  253.    for (i = 0; i < MAXSEMS; i++)          // 0 = No ListView title.
  254.        NodeStrs[ i * NODELENGTH ] = '\0'; // Kill old ListView strings.
  255.  
  256.    if (InitializeSemaphoreList() <= 0)
  257.       {
  258.       // No Semaphores known to SysBase!!
  259.       UserInfo( "No Semaphores found!", "OS ERROR??" );
  260.       }  
  261.  
  262.    GT_RefreshWindow( SemWnd, NULL );
  263.  
  264.    return( (int) TRUE );
  265. }
  266.  
  267. PRIVATE void RemoveTheSemaphore( struct SignalSemaphore *ss )
  268. {
  269.    // We should probably check that the ss->ss_QueueCount is 0 first: 
  270.  
  271.    // ObtainSemaphoreList( SysBase->SemaphoreList );
  272.    // Forbid();
  273.  
  274.    //   RemSemaphore( ss );
  275.    //   ObtainSemaphore( ss );
  276.    //   ReleaseSemaphore( ss );
  277.  
  278.    // Permit();
  279.    // ReleaseSemaphoreList( SysBase->SemaphoreList );
  280.  
  281.    UserInfo( "NOT Implemented yet!", "User Information:" );
  282.  
  283.    return;
  284. }
  285.  
  286. PRIVATE int RemoveClicked( int dummy )
  287. {
  288.    /* Do a SanityCheck() before Removing the Semaphore: */
  289.  
  290.    // Check CurrentSem for a non-NULL value
  291.  
  292.    if (CurrentSem != NULL)
  293.       {
  294.       if (SanityCheck( "Are you SURE you want to Remove %08LX?" ) != FALSE)
  295.          {
  296.          RemoveTheSemaphore( CurrentSem );
  297.  
  298.          if (InitializeSemaphoreList() <= 0)
  299.             {
  300.             // No Semaphores known to SysBase!!
  301.             UserInfo( "No Semaphores found!", "OS ERROR??" );
  302.             }
  303.  
  304.          GT_RefreshWindow( SemWnd, NULL );
  305.          }
  306.       }
  307.    else
  308.       {
  309.       // No Semaphores selected by the user:
  310.       UserInfo( "Select a Semaphores first!", "USER ERROR:" );
  311.  
  312.       return( (int) TRUE );
  313.       }
  314.  
  315.    return( (int) TRUE );
  316. }
  317.  
  318. PRIVATE void ReleaseTheSemaphore( struct SignalSemaphore *ss )
  319. {
  320.    // int i;
  321.  
  322.    // We should probably check that the ss->ss_QueueCount is 0 first: 
  323.  
  324.    // ObtainSemaphoreList( SysBase->SemaphoreList );
  325.  
  326.    // for (i = 0; i < ss->ss_NestCount; i++)
  327.    //    ReleaseSemaphore( ss );
  328.  
  329.    // ReleaseSemaphoreList( SysBase->SemaphoreList );
  330.  
  331.    UserInfo( "NOT Implemented yet!", "User Information:" );
  332.  
  333.    return;
  334. }
  335.  
  336. PRIVATE int ReleaseClicked( int dummy )
  337. {
  338.    char t[80];
  339.    
  340.    /* Do a SanityCheck() before Releasing the Semaphore: */
  341.  
  342.    // Check CurrentSem for a non-NULL value
  343.  
  344.    if (CurrentSem != NULL)
  345.       {
  346.       sprintf( &t[0], "Are you SURE you want to Release %08LX?",
  347.                       CurrentSem 
  348.              );
  349.  
  350.       if (SanityCheck( &t[0] )!= FALSE)
  351.          {
  352.          ReleaseTheSemaphore( CurrentSem );
  353.  
  354.          if (InitializeSemaphoreList() <= 0)
  355.             {
  356.             // No Semaphores known to SysBase!!
  357.             UserInfo( "No Semaphores found!", "OS ERROR??" );
  358.             }
  359.  
  360.          GT_RefreshWindow( SemWnd, NULL );
  361.          }
  362.       else
  363.          return( (int) TRUE );
  364.       }
  365.    else
  366.       {
  367.       // No Semaphores selected by the user:
  368.       UserInfo( "Select a Semaphores first!", "USER ERROR:" );
  369.  
  370.       return( (int) TRUE );
  371.       }
  372.  
  373.    return( (int) TRUE );
  374. }
  375.  
  376. PRIVATE void CloseSemWindow( void )
  377. {
  378.    if (SemWnd != NULL)
  379.       {
  380.       CloseWindow( SemWnd );
  381.       SemWnd = NULL;
  382.       }
  383.  
  384.    if (SemGList != NULL)
  385.       {
  386.       FreeGadgets( SemGList );
  387.       SemGList = NULL;
  388.       }
  389.  
  390.    if (SemFont != NULL)
  391.       {
  392.       CloseFont( SemFont );
  393.       SemFont = NULL;
  394.       }
  395.  
  396.    return;
  397. }
  398.  
  399. PRIVATE int SemCloseWindow( void )
  400. {
  401.    CloseSemWindow();
  402.    return( (int) FALSE );
  403. }
  404.  
  405. PRIVATE int CancelClicked( int dummy )
  406. {
  407.    return( SemCloseWindow() );
  408. }
  409.  
  410. PRIVATE void SemRender( void )
  411. {
  412.    struct IntuiText it;
  413.  
  414.    ComputeFont( Scr, Font, &CFont, SemWidth, SemHeight );
  415.  
  416.    CopyMem( (char *) &SemIText, (char *) &it, 
  417.             (long) sizeof( struct IntuiText )
  418.           );
  419.  
  420.    it.ITextFont = Font;
  421.  
  422.    it.LeftEdge  = 10;
  423. /*
  424.    it.LeftEdge  = CFont.OffX + ComputeX( CFont.FontX, it.LeftEdge ) 
  425.                   - (IntuiTextLength( &it ) >> 1);
  426. */
  427.    it.TopEdge   = CFont.OffY + ComputeY( CFont.FontY, it.TopEdge ) 
  428.                   - (Font->ta_YSize >> 1);
  429.  
  430.    PrintIText( SemWnd->RPort, &it, 0, 0 );
  431.    
  432.    return;
  433. }
  434.  
  435. PRIVATE int OpenSemWindow( void )
  436. {
  437.    struct NewGadget  ng;
  438.    struct Gadget    *g;
  439.    UWORD             lc, tc;
  440.    UWORD             wleft = SemLeft, wtop = SemTop, ww, wh;
  441.  
  442.    ComputeFont( Scr, Font, &CFont, SemWidth, SemHeight );
  443.  
  444.    ww = ComputeX( CFont.FontX, SemWidth );
  445.    wh = ComputeY( CFont.FontY, SemHeight );
  446.  
  447.    if ((wleft + ww + CFont.OffX + Scr->WBorRight) > Scr->Width)
  448.       wleft = Scr->Width - ww;
  449.  
  450.    if ((wtop + wh + CFont.OffY + Scr->WBorBottom) > Scr->Height)
  451.       wtop = Scr->Height - wh;
  452.  
  453.    if ((SemFont = OpenDiskFont( Font )) == NULL)
  454.       return( -5 );
  455.  
  456.    if ((g = CreateContext( &SemGList )) == NULL)
  457.       return( -1 );
  458.  
  459.    for (lc = 0, tc = 0; lc < SEM_CNT; lc++)
  460.       {
  461.       CopyMem( (char *) &SemNGad[lc], (char *) &ng, 
  462.                (long) sizeof( struct NewGadget ) 
  463.              );
  464.  
  465.       ng.ng_VisualInfo = VisualInfo;
  466.       ng.ng_TextAttr   = Font;
  467.       ng.ng_LeftEdge   = CFont.OffX + ComputeX( CFont.FontX, 
  468.                                                 ng.ng_LeftEdge
  469.                                               );
  470.  
  471.       ng.ng_TopEdge    = CFont.OffY + ComputeY( CFont.FontY, 
  472.                                                 ng.ng_TopEdge
  473.                                               );
  474.                                               
  475.       ng.ng_Width      = ComputeX( CFont.FontX, ng.ng_Width );
  476.       ng.ng_Height     = ComputeY( CFont.FontY, ng.ng_Height );
  477.  
  478.       SemGadgets[lc] = g 
  479.                      = CreateGadgetA( (ULONG) SemGTypes[lc], 
  480.                                       g, 
  481.                                       &ng, 
  482.                                       (struct TagItem *) & SemGTags[tc] 
  483.                                     );
  484.  
  485.       while (SemGTags[tc] != TAG_DONE)
  486.          tc += 2;
  487.  
  488.       tc++;
  489.  
  490.       if (g == NULL)
  491.          return( -2 );
  492.       }
  493.  
  494.    if ((SemWnd = OpenWindowTags( NULL,
  495.  
  496.                      WA_Left,        wleft,
  497.                      WA_Top,         wtop,
  498.                      WA_Width,       ww + CFont.OffX + Scr->WBorRight,
  499.                      WA_Height,      wh + CFont.OffY + Scr->WBorBottom,
  500.                      WA_IDCMP,       LISTVIEWIDCMP | BUTTONIDCMP
  501.                        | TEXTIDCMP | IDCMP_CLOSEWINDOW 
  502.                        | IDCMP_REFRESHWINDOW | IDCMP_VANILLAKEY,
  503.  
  504.                      WA_Flags,       WFLG_DRAGBAR | WFLG_DEPTHGADGET 
  505.                        | WFLG_CLOSEGADGET | WFLG_SMART_REFRESH 
  506.                        | WFLG_ACTIVATE | WFLG_RMBTRAP,
  507.                      
  508.                      WA_Gadgets,     SemGList,
  509.                      WA_Title,       SemWdt,
  510.                      WA_ScreenTitle, "System Info",
  511.                      TAG_DONE )
  512.       ) == NULL)
  513.       return( -4 );
  514.  
  515.    GT_RefreshWindow( SemWnd, NULL );
  516.  
  517.    SemRender();
  518.    
  519.    return( 0 );
  520. }
  521.  
  522. PRIVATE int SemVanillaKey( int whichkey )
  523. {
  524.    int rval = TRUE;
  525.    
  526.    switch (whichkey)
  527.       {
  528.       case 'u':
  529.       case 'U':
  530.          UpdateClicked( 0 );
  531.          break;
  532.          
  533.       case 'c':
  534.       case 'C':
  535.       case 'q':
  536.       case 'Q':
  537.          rval = SemCloseWindow();
  538.          break;
  539.       }
  540.  
  541.    return( rval );
  542. }
  543.  
  544. PRIVATE int HandleSemIDCMP( void )
  545. {
  546.    struct IntuiMessage *m;
  547.    int                  (*func)( int code );
  548.    BOOL running = TRUE;
  549.  
  550.    while (running == TRUE)
  551.       {
  552.       if ((m = GT_GetIMsg( SemWnd->UserPort ) ) == NULL )
  553.          {
  554.          (void) Wait( 1L << SemWnd->UserPort->mp_SigBit );
  555.          continue;
  556.          }
  557.  
  558.       CopyMem( (char *) m, (char *) &SemMsg, 
  559.                (long) sizeof( struct IntuiMessage ) 
  560.              );
  561.  
  562.       GT_ReplyIMsg( m );
  563.  
  564.       switch (SemMsg.Class)
  565.          {
  566.          case IDCMP_REFRESHWINDOW:
  567.             GT_BeginRefresh( SemWnd );
  568.             SemRender();
  569.             GT_EndRefresh( SemWnd, TRUE );
  570.             break;
  571.  
  572.          case IDCMP_CLOSEWINDOW:
  573.             running = SemCloseWindow();
  574.             break;
  575.  
  576.          case IDCMP_VANILLAKEY:
  577.             running = SemVanillaKey( SemMsg.Code );
  578.             break;
  579.  
  580.          case IDCMP_GADGETUP:
  581.          case IDCMP_GADGETDOWN:
  582.             func = (void *) ((struct Gadget *) SemMsg.IAddress)->UserData;
  583.             if (func != NULL)
  584.                running = func( (int) SemMsg.Code );
  585.             break;
  586.          }
  587.       }
  588.  
  589.    return( running );
  590. }
  591.  
  592. PUBLIC int HandleSemaphoreLV( void )
  593. {
  594.    int i = 0;
  595.  
  596.    if (SetupSystemList( &OpenSemWindow ) < 0)
  597.       {
  598.       (void) Handle_Problem( "Couldn't open a System ListViewer!", 
  599.                              "Allocation Problem:", NULL 
  600.                            );
  601.       return( -1 );
  602.       }
  603.  
  604.    // Disable buttons until user selects a Semaphore from the ListView:
  605.  
  606.    GT_SetGadgetAttrs( SemGadgets[ Remove ], SemWnd, NULL,
  607.                       GA_Disabled, TRUE, TAG_DONE 
  608.                     );
  609.  
  610.    GT_SetGadgetAttrs( SemGadgets[ Release ], SemWnd, NULL,
  611.                       GA_Disabled, TRUE, TAG_DONE 
  612.                     );
  613.    
  614.    SetNotifyWindow( SemWnd ); // For Handle_Problem().
  615.   
  616.    lvm.lvm_NodeStrs   = &NodeStrs[0];
  617.    lvm.lvm_Nodes      = &SempNodes[0];
  618.    lvm.lvm_NumItems   = MAXSEMS;
  619.    lvm.lvm_NodeLength = NODELENGTH;
  620.  
  621.    SetupList( &SempList, &lvm );   
  622.  
  623.    (void) InitializeSemaphoreList();
  624.  
  625.    GT_SetGadgetAttrs( LISTVIEWGADGET, SemWnd, NULL,
  626.                       GTLV_Labels,       &SempList,
  627.                       GTLV_ShowSelected, SEM_DISPLAY,
  628.                       GTLV_Selected,     0,
  629.                       GTLV_ItemHeight,   12,
  630.                       TAG_END
  631.                     );
  632.  
  633.    GT_RefreshWindow( SemWnd, NULL );
  634.  
  635.    (void) HandleSemIDCMP();
  636.    
  637.    ShutdownSystemList();
  638.  
  639.    return( 0 );
  640. }
  641.  
  642. #ifdef DEBUG
  643.  
  644. PUBLIC int main( void )
  645. {
  646.    return( HandleSemaphoreLV() );
  647. }
  648.  
  649. #endif
  650.  
  651. /* --------------------- END of SysSemaphore.c file! --------------- */
  652.